import com.air.DemoRun;
import com.air.thread.pool.DoThreadPoolDemo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * CountDownLatch:
 * latch(门闩)，门闩的含义:把门锁起来，不让里面的线程跑出来，因此，这个工具通常用来控制线程等待，它可以让某个线程等待直到倒计时结束，再开始执行。
 * CountDownLatch的构造函数接收一个整数N作为参数，即当前这个计数器个数。
 * <p>
 * CountDownLatch这个类能够使一个线程等待其他线程完成各自的工作后再执行。
 * CountDownLatch通过一个计数器来实现的，计数器的初始值为线程的数量，每当一个线程完成了自己的任务后，计数器的只就减1，当计数器的值到达0时，表示所有的线程已经完成了任务，然后闭锁上等待的线程就可以恢复执行任务。
 * 主线程必须在启动其他线程后立即调用CountDownLatch.await()方法，这样主线程就会在这个方法上拥塞，直到其他线程完成各自的任务。
 * 其他线程在完成自己的任务后，需要通知CountDownLatch对象
 * 注意计算器的值一直没有减为0，此时我们不能让主线程一直等待，所以可以使用await(long time,TimeUnit unit)，等待特定的时间后，就不再阻塞当前线程。
 * <p>
 * CyclicBarrier(同步屏障):
 * 当一组线程到达一个屏障时被阻塞，直到最后一个线程到达屏障时，屏障才会开门，所有被屏障拦截的线程才会继续执行。
 * CyclicBarrier的构造方法是CyclicBarrier(int parties)，其参数表示屏障拦截的线程数量，每个线程调用await方法告诉CyclicBarrier我已经到达了屏障，然后当前线程被阻塞。
 *
 * @author shent
 */
@SpringBootTest(classes = DemoRun.class)
public class ThreadPool {
    @Autowired
    DoThreadPoolDemo doThreadPoolDemo;

    @Test
    public void testThreadPool() {
        CountDownLatch countDownLatch = new CountDownLatch(6);
        System.out.println("开始执行多线程任务1111111111:::" + System.currentTimeMillis());
        for (int i = 0; i <= 5; i++) {
            doThreadPoolDemo.doThreadPool(countDownLatch, i);
        }
        try {
            //主线程必须在启动其他线程后立即调用CountDownLatch.await()方法，这样主线程就会在这个方法上拥塞，直到其他线程完成各自的任务。
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("主线程继续执行222222222222222:::::" + Thread.currentThread().getName());
    }
}
